package com.leosoft.heatmonitor.service.transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import com.leosoft.heatmonitor.dao.DeviceDAO;
import com.leosoft.heatmonitor.dao.ProjectDAO;
import com.leosoft.heatmonitor.dao.TargetDAO;
import com.leosoft.heatmonitor.dao.UserDAO;
import com.leosoft.heatmonitor.model.Device;
import com.leosoft.heatmonitor.model.Project;
import com.leosoft.heatmonitor.model.Target;
import com.leosoft.heatmonitor.model.User;

@Component("targetService")
public class TargetService {
	@Autowired
	private TargetDAO targetDAO;
	@Autowired
	private ProjectDAO projectDAO;
	@Autowired
	private UserDAO userDAO;
	@Autowired
	private DeviceDAO deviceDAO;

	public Map<String, Object> list(int startIndex, int length, List<String[]> wherePart, List<String[]> odrerPart,
			String username) {
		User user = userDAO.getUserByName(username);
		if (!user.getRoles().isEmpty()) {
			if (user.getRoles().get(0).getRole().equals("PM")) {
				return targetDAO.list(startIndex, length, wherePart, odrerPart, user.getId());
			} else {
				return targetDAO.list(startIndex, length, wherePart, odrerPart, "");
			}
		}

		return null;
	}

	public boolean create(String projectId, String building, String door, String user, String key, String name,
			String telephone) {
		if (targetDAO.notExist(projectId, building, door, user)) {
			Project project = projectDAO.getProjectById(projectId);
			targetDAO.create(project, building, door, user, key, name, telephone);
			return true;
		}
		return false;
	}

	public void delete(String id) {
		targetDAO.delete(id);

	}

	public Project loadProject(String id) {
		Project project = targetDAO.loadProject(id);
		project.setUsers(null);
		return project;
	}

	public void update(String id, String projectId, String building, String door, String user, String key, String name,
			String telephone) {
		Project project = projectDAO.getProjectById(projectId);
		targetDAO.update(id, project, building, door, user, key, name, telephone);
	}

	public List<Map<String, Object>> loadTarget(String projectId, String deviceId) {
		return targetDAO.loadTarget(projectId, deviceId);
	}

	public List<Object> loadBuilding(String projectId) {
		return targetDAO.loadBuilding(projectId);
	}

	public List<Object> loadDoor(String projectId, String building) {
		return targetDAO.loadDoor(projectId, building);
	}

	public List<String> suggestBuilding(String building, String username) {
		User user = userDAO.getUserByName(username);
		if (!user.getRoles().isEmpty()) {
			if (user.getRoles().get(0).getRole().equals("PM")) {
				return targetDAO.suggestBuilding(building, user.getId());
			} else {
				return targetDAO.suggestBuilding(building, "");
			}
		}

		return null;

	}

	public List<String> suggestDoor(String door, String username) {
		User user = userDAO.getUserByName(username);
		if (!user.getRoles().isEmpty()) {
			if (user.getRoles().get(0).getRole().equals("PM")) {
				return targetDAO.suggestDoor(door, user.getId());
			} else {
				return targetDAO.suggestDoor(door, "");
			}
		}
		return null;
	}

	public List<String> suggestUser(String target, String username) {
		User user = userDAO.getUserByName(username);
		if (!user.getRoles().isEmpty()) {
			if (user.getRoles().get(0).getRole().equals("PM")) {
				return targetDAO.suggestUser(target, user.getId());
			} else {
				return targetDAO.suggestUser(target, "");
			}
		}
		return null;
	}

	public List<String> suggestKey(String key, String username) {
		User user = userDAO.getUserByName(username);
		if (!user.getRoles().isEmpty()) {
			if (user.getRoles().get(0).getRole().equals("PM")) {
				return targetDAO.suggestKey(key, user.getId());
			} else {
				return targetDAO.suggestKey(key, "");
			}
		}
		return null;
	}

	public boolean upload(MultipartFile file, String projectId) {
		Workbook wb = null;
		Project project = projectDAO.getProjectById(projectId);
		try {
			wb = WorkbookFactory.create(file.getInputStream());
			Sheet sheet = wb.getSheetAt(0);
			int i = 0;
			List<Target> targets = new ArrayList<>();
			for (Row row : sheet) {
				if (i > 0) {
					Target target = new Target();
					row.getCell(0).setCellType(1);
					target.setKey(row.getCell(0).getStringCellValue());
					row.getCell(1).setCellType(1);
					target.setBuilding(row.getCell(1).getStringCellValue());
					row.getCell(2).setCellType(1);
					target.setDoor(row.getCell(2).getStringCellValue());
					row.getCell(3).setCellType(1);
					target.setUser(row.getCell(3).getStringCellValue());
					if (row.getCell(4) != null) {
						row.getCell(4).setCellType(1);
						target.setName(row.getCell(4).getStringCellValue());
					}
					if (row.getCell(5) != null) {
						row.getCell(5).setCellType(1);
						target.setTelephone(row.getCell(5).getStringCellValue());
					}

					target.setProject(project);
					if (targetDAO.notExist(projectId, row.getCell(1).getStringCellValue(), row.getCell(2)
							.getStringCellValue(), row.getCell(3).getStringCellValue())) {
						targets.add(target);
					}
				}
				i++;
			}
			targetDAO.upload(targets);
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}

	private String getCellValue(Cell cell) {
		String result = null;
		switch (cell.getCellType()) {
		case Cell.CELL_TYPE_STRING:
			result = cell.getRichStringCellValue().getString();
			break;
		case Cell.CELL_TYPE_NUMERIC:
			if (DateUtil.isCellDateFormatted(cell)) {
				result = cell.getDateCellValue().toString();
			} else {
				// result = cell.getNumericCellValue();
			}
			break;
		case Cell.CELL_TYPE_BOOLEAN:
			result = String.valueOf(cell.getBooleanCellValue());
			break;
		case Cell.CELL_TYPE_FORMULA:
			result = cell.getCellFormula().toString();
			break;
		default:
			result = "";
		}
		return result;
	}
}
